package com.jivam.lottery.data;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;





import com.jivam.lottery.model.KeyFormula;
import com.jivam.lottery.model.Num;
import com.jivam.lottery.model.PeriodNum;
import com.jivam.lottery.util.Constants;

/**
 * 导入数据的基本类
 * @author Jivam
 */
public class DataImport {
	
	private static final File ptxt = new File(Constants.PATH_PERIOD);
	private static final File ftxt = new File(Constants.PATH_FORMULA);
	private static String importMsg = "";
	private static Map<String,int[]> key_position ;//Key和Mapping的对应关系
	
	private DataImport(){
	}
	
	/**
	 * 判断是否强制导入，当数据版本更新时，需要重新导入数据
	 * @return 是否需要导入
	 */
	public static boolean needImport(){
		boolean needImport = false;
		String version = DataUtil.getData(Constants.KEY_DATA_VERSION);
		if(version == null)
			return true;
		if(!Constants.DATA_VERSION.equals(version))
			return true;
		if(DataCalculator.pns.size()<Constants.MAX_PERIOD)
			return true;
		return needImport;
	}

	/**
	 * KEY 转换为 位置信息
	 * @param key
	 * @return
	 */
	public static int[] keyToPosition(String key){
		if(key_position == null){
			key_position = new HashMap<String, int[]>();
			key_position.put(Constants.KEY_A, new int[]{Constants.POSTION_A});
			key_position.put(Constants.KEY_B, new int[]{Constants.POSTION_B});
			key_position.put(Constants.KEY_C, new int[]{Constants.POSTION_C});
			key_position.put(Constants.KEY_D, new int[]{Constants.POSTION_D});
			key_position.put(Constants.KEY_E, new int[]{Constants.POSTION_E});
			key_position.put(Constants.KEY_F, new int[]{Constants.POSTION_F});
			key_position.put(Constants.KEY_G, new int[]{Constants.POSTION_G});
			key_position.put(Constants.KEY_AD, new int[]{Constants.POSTION_A,Constants.POSTION_D});
			key_position.put(Constants.KEY_BD, new int[]{Constants.POSTION_B,Constants.POSTION_D});
			key_position.put(Constants.KEY_AB, new int[]{Constants.POSTION_A,Constants.POSTION_B});
			key_position.put(Constants.KEY_AC, new int[]{Constants.POSTION_A,Constants.POSTION_C});
			key_position.put(Constants.KEY_BC, new int[]{Constants.POSTION_B,Constants.POSTION_C});
			key_position.put(Constants.KEY_CD, new int[]{Constants.POSTION_C,Constants.POSTION_D});
			key_position.put(Constants.KEY_SUM, new int[]{Constants.POSTION_SUM});
			key_position.put(Constants.KEY_KD, new int[]{Constants.POSTION_KD});
		}
		return key_position.get(key);
	}
	
	
	/**
	 * 历史期数导入
	 * @param ptxt
	 * @return
	 */
	private static List<PeriodNum> getHistoryPeroiod() {
		List<PeriodNum> nums = null;
		FileReader fr = null;
		BufferedReader br = null;
		try{
			fr = new FileReader(ptxt);
			br = new BufferedReader(fr);
			nums = new ArrayList<PeriodNum>(1500);
			PeriodNum pn = null;
			String line = null;
			int periodNum, pid;
			String[] tmp;
			while ((line = br.readLine()) != null) {
				line = line.trim();
				if(!line.isEmpty() && line.indexOf(",") > 0){
					try {
						tmp = line.split(",");
						pid = Integer.parseInt(tmp[0]);
						periodNum = Integer.parseInt(tmp[1]);
						pn = new PeriodNum(periodNum,pid);
						nums.add(pn);
					} catch (Exception e) {
						continue;
					}
				}else{
					continue;
				}
			}
		} catch (Exception e) {
			DataUtil.writeLog("历史期数导入出错！", e);
		}finally{
			 try{if(fr != null);fr.close();}catch (Exception e){}
			 try{if(br != null);br.close();}catch (Exception e){}
		}
		return nums;
	}
	
	/**
	 * 公式导入方法
	 * @param ftxt
	 * @return
	 */
	private static void getKeyFormula(final List<KeyFormula> kfs,final Map<String,String> fmap) {
		FileReader fr = null;
		BufferedReader br = null;
		try{
			fr = new FileReader(ftxt);
			br = new BufferedReader(fr);
			//公式出现顺序 FIXME instead of LinkedHashMap
			Map<String, KeyFormula> map = new LinkedHashMap<String, KeyFormula>();//公式集合
			String line = null;
			String[] tmp;
			while ((line = br.readLine()) != null) {
				line = line.trim();
				try {
					if(line.indexOf(Constants.KEY_FORMULA_MAP_LEFT_FLAG) > 0){
						tmp = line.split(Constants.KEY_FORMULA_MAP_LEFT_FLAG);
						if(!tmp[0].isEmpty() && !tmp[1].isEmpty()){
							fmap.put(tmp[0], tmp[1]);
						}
					}else if(line.indexOf(Constants.KEY_FORMULA_LEFT_FLAG) > 0){
						tmp = line.split(Constants.KEY_FORMULA_LEFT_FLAG);
						getKeyFormula(map,tmp[0]).addExpression(tmp[1]);//添加公式左边项
					}else if(line.indexOf(Constants.KEY_FORMULA_RIGHT_FLAG) > 0){
						tmp = line.split(Constants.KEY_FORMULA_RIGHT_FLAG);
						getKeyFormula(map,tmp[0]).addFormula(tmp[1]);//添加公式右边项
					}
				} catch (Exception e) {
					continue;
				}
			}
			for(KeyFormula kf : map.values()){
				if(kf != null && kf.getFormulas() != null 
						&& !kf.getExpressions().isEmpty() && !kf.getFormulas().isEmpty()){//当公式左右都不为空时才添加到最终列表
					kfs.add(kf);
				}
			}
		} catch (Exception e) {
			DataUtil.writeLog("公式导入出错！", e);
		}finally{
			 try{if(fr != null);fr.close();}catch (Exception e){}
			 try{if(br != null);br.close();}catch (Exception e){}
		}
	}
	
	private static KeyFormula getKeyFormula(final Map<String, KeyFormula> map,String key){
		KeyFormula pn = null;
		if(map.containsKey(key)){
			pn = map.get(key);
		}else{
			pn = new KeyFormula(key);
			map.put(key, pn);
		}
		return pn;
	}
	
	/**
	 * 导入历史数据
	 * @return 导入是否成功
	 */
	public static boolean importFile(){
		if(!ptxt.exists() || !ftxt.exists()){
			importMsg = "导入失败，请检查下列文件是否存在\n"
					+Constants.PATH_DIR+Constants.PATH_PERIOD+"\n"
					+Constants.PATH_DIR+Constants.PATH_FORMULA;
			return false;
		}
		try {
			List<PeriodNum> nums = getHistoryPeroiod();
			if(nums == null || nums.size() < Constants.IMPORT_MIN_PERIOD){
				importMsg = "导入期数失败, 至少导入"+Constants.IMPORT_MIN_PERIOD+"期！";
				return false;
			}
			resetData();
			DataCalculator.importPeriods(nums);
			importMsg = "导入成功, 共导入"+nums.size()+"期！";
			return true;
		} catch (Exception e) {
			DataUtil.loadData();//出错恢复
			DataCalculator.reload();
			importMsg = "导入异常，请联系开发者！";
			DataUtil.writeLog("导入出错", e);
			e.printStackTrace();
			return false;
		}
		
	}
	
	/**
	 * 重置数据
	 */
	private static void resetData() {
		DataUtil.clearData();
		//Num Panel
		List<List<Num>> numls = new ArrayList<List<Num>>();
		List<Num> temp = null;
		for(String key : Constants.KEY_NUM){
			temp  = new ArrayList<Num>(10);
			for(int num = 0;num < 10;num++){
				temp.add(new Num(num, key,keyToPosition(key)));
			}
			numls.add(temp);
		}
		DataUtil.addData(Constants.KEY_NUMS, numls);
		//Period Panel
		DataUtil.addData(Constants.KEY_PERIOD_NUM, new LinkedList<PeriodNum>());
		DataUtil.addData(Constants.KEY_ALL_PERIOD_NUM, new HashMap<String,Integer>());
		//Formula Panels
		List<KeyFormula> keyformula = new ArrayList<KeyFormula>();
		Map<String,String> fmap = new HashMap<String, String>();
		//Formula Map	
		getKeyFormula(keyformula, fmap);
		DataUtil.addData(Constants.KEY_FORMULA, keyformula);
		DataUtil.addData(Constants.KEY_FORMULA_MAP, fmap);
		DataCalculator.reload();
	}
	
	/**
	 * 获取错误提示
	 * @return
	 */
	public static String getImportMsg() {
		return importMsg;
	}
	
}
